using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace VistaBatterySaver
{
    internal static class NativeMethods
    {
        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern void DwmEnableComposition(bool bEnable);

        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern bool DwmIsCompositionEnabled();

        [DllImport("kernel32.dll")]
        public static extern bool SetProcessWorkingSetSize(IntPtr procHandle, Int32 min, Int32 max);

        [DllImport("kernel32.dll")]
        public static extern int Process32First(IntPtr hSnapshot,
                                 ref PROCESSENTRY32 lppe);

        [DllImport("kernel32.dll")]
        public static extern int Process32Next(IntPtr hSnapshot,
                                ref PROCESSENTRY32 lppe);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags,
                                               uint th32ProcessID);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool CloseHandle(IntPtr hSnapshot);

        public const uint TH32CS_SNAPPROCESS = 0x00000002;

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool TerminateProcess(IntPtr hProcess, int uExitCode);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg,
           UIntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags,
           uint uTimeout, out UIntPtr lpdwResult);
        [return: MarshalAs(UnmanagedType.Bool)]

        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam,
           IntPtr lParam);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnumThreadWindows(uint dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);

        public delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);

        [StructLayout(LayoutKind.Sequential)]
        public struct PROCESSENTRY32
        {
            public uint dwSize;
            public uint cntUsage;
            public uint th32ProcessID;
            public IntPtr th32DefaultHeapID;
            public uint th32ModuleID;
            public uint cntThreads;
            public uint th32ParentProcessID;
            public int pcPriClassBase;
            public uint dwFlags;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szExeFile;
        }

        [Flags]
        enum SendMessageTimeoutFlags : uint
        {
            SMTO_NORMAL = 0x0000,
            SMTO_BLOCK = 0x0001,
            SMTO_ABORTIFHUNG = 0x0002,
            SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
        }



        internal const uint WM_CLOSE = 0x10;
        const uint WM_QUIT = 0x12;
        const uint WM_QUERYENDSESSION = 0x11;

        [StructLayout(LayoutKind.Sequential)]
        public struct OSVERSIONINFOEX
        {
            public int dwOSVersionInfoSize;
            public int dwMajorVersion;
            public int dwMinorVersion;
            public int dwBuildNumber;
            public int dwPlatformId;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
            public string szCSDVersion;
            public short wServicePackMajor;
            public short wServicePackMinor;
            public short wSuiteMask;
            public byte wProductType;
            public byte wReserved;
        }

        [DllImport("kernel32.dll")]
        public static extern bool GetVersionEx(ref OSVERSIONINFOEX osVersionInfo);

        const int VER_NT_WORKSTATION = 1;
        const int VER_NT_DOMAIN_CONTROLLER = 2;
        const int VER_NT_SERVER = 3;
        const int VER_SUITE_SMALLBUSINESS = 1;
        const int VER_SUITE_ENTERPRISE = 2;
        const int VER_SUITE_TERMINAL = 16;
        const int VER_SUITE_DATACENTER = 128;
        const int VER_SUITE_SINGLEUSERTS = 256;
        const int VER_SUITE_PERSONAL = 512;
        const int VER_SUITE_BLADE = 1024;


        [DllImport("kernel32.dll")]
        public static extern bool GetProductInfo(int dwOSMajorVersion, int dwOSMinorVersion, int dwSpMajorVersion, int dwSpMinorVersion, out int pdwReturnedProductType);

        public enum V6ProductType
        {
            PRODUCT_BUSINESS = 0x00000006,// Business Edition 
            PRODUCT_BUSINESS_N = 0x00000010,// Business Edition 
            PRODUCT_CLUSTER_SERVER = 0x00000012,// Cluster Server Edition 
            PRODUCT_DATACENTER_SERVER = 0x00000008,// Server Datacenter Edition (full installation) 
            PRODUCT_DATACENTER_SERVER_CORE = 0x0000000C,// Server Datacenter Edition (core installation) 
            PRODUCT_ENTERPRISE = 0x00000004,// Enterprise Edition 
            PRODUCT_ENTERPRISE_N = 0x0000001B,// Enterprise Edition 
            PRODUCT_ENTERPRISE_SERVER = 0x0000000A,// Server Enterprise Edition (full installation) 
            PRODUCT_ENTERPRISE_SERVER_CORE = 0x0000000E,// Server Enterprise Edition (core installation) 
            PRODUCT_ENTERPRISE_SERVER_IA64 = 0x0000000F,// Server Enterprise Edition for Itanium-based Systems 
            PRODUCT_HOME_BASIC = 0x00000002,// Home Basic Edition 
            PRODUCT_HOME_BASIC_N = 0x00000005,// Home Basic Edition 
            PRODUCT_HOME_PREMIUM = 0x00000003,// Home Premium Edition 
            PRODUCT_HOME_PREMIUM_N = 0x0000001A,// Home Premium Edition 
            PRODUCT_HOME_SERVER = 0x00000013,// Home Server Edition 
            PRODUCT_SERVER_FOR_SMALLBUSINESS = 0x00000018,// Server for Small Business Edition 
            PRODUCT_SMALLBUSINESS_SERVER = 0x00000009,// Small Business Server 
            PRODUCT_SMALLBUSINESS_SERVER_PREMIUM = 0x00000019,// Small Business Server Premium Edition 
            PRODUCT_STANDARD_SERVER = 0x00000007,// Server Standard Edition (full installation) 
            PRODUCT_STANDARD_SERVER_CORE = 0x0000000D,// Server Standard Edition (core installation) 
            PRODUCT_STARTER = 0x0000000B,// Starter Edition 
            PRODUCT_STORAGE_ENTERPRISE_SERVER = 0x00000017,// Storage Server Enterprise Edition 
            PRODUCT_STORAGE_EXPRESS_SERVER = 0x00000014,// Storage Server Express Edition 
            PRODUCT_STORAGE_STANDARD_SERVER = 0x00000015,// Storage Server Standard Edition 
            PRODUCT_STORAGE_WORKGROUP_SERVER = 0x00000016,// Storage Server Workgroup Edition 
            PRODUCT_UNDEFINED = 0x00000000,// An unknown product 
            PRODUCT_ULTIMATE = 0x00000001,// Ultimate Edition 
            PRODUCT_ULTIMATE_N = 0x0000001C,// Ultimate Edition 
            PRODUCT_WEB_SERVER = 0x00000011// Web Server Edition 
        }

        public static readonly Guid GUID_MAX_POWER_SAVINGS = new Guid(0xA1841308, 0x3541, 0x4FAB, 0xBC, 0x81, 0xF7, 0x15, 0x56, 0xF2, 0x0B, 0x4A);
        public static readonly Guid GUID_MIN_POWER_SAVINGS = new Guid(0x8C5E7FDA, 0xE8BF, 0x4A96, 0x9A, 0x85, 0xA6, 0xE2, 0x3A, 0x8C, 0x63, 0x5C);
        public static readonly Guid GUID_TYPICAL_POWER_SAVINGS = new Guid(0x381B4222, 0xF694, 0x41F0, 0x96, 0x85, 0xFF, 0x5B, 0xB2, 0x60, 0xDF, 0x2E);

        public static readonly Guid NO_SUBGROUP_GUID = new Guid(0xfea3413e, 0x7e05, 0x4911, 0x9a, 0x71, 0x70, 0x03, 0x31, 0xf1, 0xc2, 0x94);
        public static readonly Guid GUID_VIDEO_SUBGROUP = new Guid(0x7516b95f, 0xf776, 0x4464, 0x8c, 0x53, 0x06, 0x16, 0x7f, 0x40, 0xcc, 0x99);

        public const uint ERROR_INVALID_PARAMETER = 87;
        public const uint ERROR_MORE_DATA = 234;
        public const uint ERROR_SUCCESS = 0;
        public const uint ERROR_ERRORS_ENCOUNTERED = 774;

        public enum POWER_DATA_ACCESSOR
        { 
            ACCESS_SCHEME = 16,
            ACCESS_SUBGROUP = 17,
            ACCESS_INDIVIDUAL_SETTING = 18
        }

        [DllImportAttribute("powrprof.dll", EntryPoint = "PowerEnumerate")]
        public static extern uint PowerEnumerate(IntPtr RootPowerKey, IntPtr SchemeGuid, IntPtr SubGroupOfPowerSettingsGuid, POWER_DATA_ACCESSOR AccessFlags, uint Index, ref Guid Buffer, ref uint BufferSize);
        [DllImportAttribute("powrprof.dll", EntryPoint = "PowerReadFriendlyName")]
        public static extern uint PowerReadFriendlyName(IntPtr RootPowerKey, ref Guid SchemeGuid, IntPtr SubGroupOfPowerSettingsGuid, IntPtr PowerSettingGuid, IntPtr Buffer, ref uint BufferSize);
        [DllImportAttribute("powrprof.dll", EntryPoint = "PowerGetActiveScheme")]
        public static extern uint PowerGetActiveScheme(IntPtr UserPowerKey, out IntPtr ActivePolicyGuid);
        [DllImportAttribute("powrprof.dll", EntryPoint = "PowerSetActiveScheme")]
        public static extern uint PowerSetActiveScheme(IntPtr UserPowerKey, ref Guid ActivePolicyGuid);


        public enum POWER_INFORMATION_LEVEL
        { 
            AdministratorPowerPolicy = 9,
            LastSleepTime = 15,
            LastWakeTime = 14,
            ProcessorInformation = 11,
            ProcessorPowerPolicyAc = 18,
            ProcessorPowerPolicyCurrent = 22,
            ProcessorPowerPolicyDc = 19,
            SystemBatteryState = 5,
            SystemExecutionState = 16,
            SystemPowerCapabilities = 4,
            SystemPowerInformation = 12,
            SystemPowerPolicyAc = 0,
            SystemPowerPolicyCurrent = 8,
            SystemPowerPolicyDc = 1,
            SystemReserveHiberFile = 10,
            SystemWakeSource = 35,
            VerifyProcessorPowerPolicyAc = 20,
            VerifyProcessorPowerPolicyDc = 21,
            VerifySystemPolicyAc = 2,
            VerifySystemPolicyDc = 3
        }

        [StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct SYSTEM_BATTERY_STATE
        {
            public byte AcOnLine;
            public byte BatteryPresent;
            public byte Charging;
            public byte Discharging;
            [MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I1)]
            public byte[] Spare1;
            public UInt32 MaxCapacity;
            public UInt32 RemainingCapacity;
            public Int32 Rate;
            public UInt32 EstimatedTime;
            public UInt32 DefaultAlert1;
            public UInt32 DefaultAlert2;
        }

        [DllImport("powrprof.dll", EntryPoint="CallNtPowerInformation", SetLastError = true)]
        public static extern UInt32 CallNtPowerInformation(POWER_INFORMATION_LEVEL InformationLevel, IntPtr lpInputBuffer, UInt32 nInputBufferSize, IntPtr lpOutputBuffer, UInt32 nOutputBufferSize);

        [DllImport("kernel32.dll", EntryPoint = "GetProcAddress", CharSet = CharSet.Ansi)]
        public static extern System.IntPtr GetProcAddress(System.IntPtr hModule, string lpProcName);
        [DllImport("kernel32.dll", EntryPoint = "FreeLibrary", CharSet = CharSet.Ansi)]
        public static extern int FreeLibrary(System.IntPtr hLibModule);
        [DllImport("kernel32.dll", EntryPoint = "LoadLibraryA", CharSet = CharSet.Ansi)]
        public static extern System.IntPtr LoadLibrary(string lpLibFileName);



        [DllImport("user32.dll")]
        public static extern int SetWindowLong(IntPtr window, int index, int value);
        [DllImport("user32.dll")]
        public static extern int GetWindowLong(IntPtr window, int index);


        public const int GWL_EXSTYLE = -20;
        public const int WS_EX_TOOLWINDOW = 0x00000080;
        public const int WS_EX_APPWINDOW = 0x00040000;

        [DllImport("WININET", CharSet = CharSet.Auto)]
        public static extern bool InternetGetConnectedState(
            ref InternetConnectionState lpdwFlags,
            int dwReserved);

        [Flags]
        public enum InternetConnectionState : int
        {
            INTERNET_CONNECTION_MODEM = 0x1,
            INTERNET_CONNECTION_LAN = 0x2,
            INTERNET_CONNECTION_PROXY = 0x4,
            INTERNET_RAS_INSTALLED = 0x10,
            INTERNET_CONNECTION_OFFLINE = 0x20,
            INTERNET_CONNECTION_CONFIGURED = 0x40
        }


    }
}
